package edu.unh.sustain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * Displays route 4A of Wildcat Transit as an expandable list.  This means
 * that each stop will appear as a top level "group", and after it is touched
 * it will expand to show the different times that the bus will service
 * that stop.
 * 
 * Displays schedule for route 4A on weekdays, weekends, and reduced service.
 * @author Blake Janelle
 *
 */
public class Route5Activity extends ExpandableListActivity {
	
	String timeframe;
	Context ct = this;
	int spinnerState = 0;
	final int GROUP_HEIGHT = 63;
	final int CHILD_HEIGHT = 30;
	HashMap<String,Integer> runs = new HashMap<String,Integer>();
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    
	    timeframe = getTimeframe(savedInstanceState);
	    ArrayAdapter<CharSequence> adapter = null;
	    this.addStringRuns();
	    setContentView(R.layout.route5);
	    
	    // set up the spinner that controls the current timeframe
	    adapter = ArrayAdapter.createFromResource(
	            this, R.array.r5_timeframes, android.R.layout.simple_spinner_item);
	    Spinner spinner = (Spinner) findViewById(R.id.timeframes);
	    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	    spinner.setAdapter(adapter);
	    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
	    
	    // set up an expandable list that groups every stop, and when pressed, expands to display each stop time
	    SimpleExpandableListAdapter lstAdapter =
				new SimpleExpandableListAdapter
				(
					this,
					createGroupList(), 						// Creating group List.
					R.layout.expand_group_row,				// Group item layout XML.
					new String[] { "Group Item" },			// the key of group item.
					new int[] { R.id.row },				// ID of each group item.-Data under the key goes into this TextView.
					createChildList(),						// childData describes second-level entries.
					R.layout.expand_child_row,				// Layout for sub-level entries(second level).
					new String[] {"Sub Item"},				// Keys in childData maps to display.
					new int[] { R.id.grp_child }			// Data under the keys above go into these TextViews.
				);
					
	    ExpandableListView a = (ExpandableListView)findViewById(android.R.id.list);
	    a.setAdapter(lstAdapter);
	    //a.setOnGroupExpandListener(new MyOnGroupExpandListener());
	    //a.setOnGroupCollapseListener(new MyOnGroupCollapseListener());
		
	    // set text box labels for the corresponding timeframe
	    if( timeframe.equals("weekends"))
	    {
	    	spinnerState = 1;
	    	TextView title = (TextView)findViewById(R.id.textView1);
	    	title.setText(R.string.r5w_title);
	    	TextView route = (TextView)findViewById(R.id.textView2);
	    	route.setText(R.string.r5w_route);
	    	TextView range = (TextView)findViewById(R.id.textView3);
	    	range.setText(R.string.r5w_range);
		    spinner.setSelection(spinnerState);
	    }
	    else if( timeframe.equals("reduced"))
	    {
	    	spinnerState = 2;
	    	TextView title = (TextView)findViewById(R.id.textView1);
	    	title.setText(R.string.r5r_title);
	    	TextView route = (TextView)findViewById(R.id.textView2);
	    	route.setText(R.string.r5r_route);
	    	TextView range = (TextView)findViewById(R.id.textView3);
	    	range.setText(R.string.r5r_range);
		    spinner.setSelection(spinnerState);
	    }
	    else
	    {
	    	TextView title = (TextView)findViewById(R.id.textView1);
	    	title.setText(R.string.r5_title);
	    	TextView route = (TextView)findViewById(R.id.textView2);
	    	route.setText(R.string.r5_route);
	    	TextView range = (TextView)findViewById(R.id.textView3);
	    	range.setText(R.string.r5_range);
		    spinner.setSelection(spinnerState);
	    }
	}
	
	/**
	 * Create list of stops which are the "groups" of the expandable list
	 * 
	 * @return List<HashMap<String,String>>
	 */
	private List<HashMap<String,String>> createGroupList()
	{
		String[] stops;
				
		if(timeframe.equals("weekdays"))
			stops = getResources().getStringArray(R.array.r5stops);
		else if(timeframe.equals("weekends"))
			stops = getResources().getStringArray(R.array.r5wstops);
		else
			stops = getResources().getStringArray(R.array.r5rstops);
		
		ArrayList<HashMap<String,String>> result = new ArrayList<HashMap<String,String>>();
		  
		for( int i = 0 ; i < stops.length; i++ )
		{
			HashMap<String,String> m = new HashMap<String,String>();
			m.put( "Group Item", stops[i] );
			result.add( m );
		}
		
		return (List<HashMap<String,String>>)result;
    }

	/**
	 * Create list of times for each stop.
	 * 
	 * @return List<ArrayList<HashMap<String,String>>>
	 */
	private List<ArrayList<HashMap<String,String>>> createChildList()
	{
		String[] stops;
		String prefix;
		
		if(timeframe.equals("weekdays"))
		{
			stops = getResources().getStringArray(R.array.r5stops);
			prefix = "r5stop";
		}
		else if(timeframe.equals("weekends"))
		{
			stops = getResources().getStringArray(R.array.r5wstops);
			prefix = "r5wstop";
		}
		else
		{
			stops = getResources().getStringArray(R.array.r5rstops);
			prefix = "r5rstop";
		}
		
		ArrayList<ArrayList<HashMap<String,String>>> result = new ArrayList<ArrayList<HashMap<String,String>>>();
		
		for( int i = 0 ; i < stops.length; i++ )
		{
			String index = prefix + (i+1);
			String[] run = getResources().getStringArray(runs.get(index));
			ArrayList<HashMap<String,String>> secList = new ArrayList<HashMap<String,String>>();
			
			for( int n = 0 ; n < run.length ; n++ )
			{
				HashMap<String,String> child = new HashMap<String,String>();
				child.put( "Sub Item", run[n] );
				secList.add( child );
			}
			
			result.add( secList );
		}
		return result;
	}
	
	/**
	 * Extracts the timeframe data from the Instance and returns it
	 * 
	 * @param savedInstanceState previous state
	 * @return the string or null
	 */
	private String getTimeframe(Bundle savedInstanceState)
	{
		String ret = null;
		
		if( savedInstanceState != null )
	    {
	    	ret = (String) savedInstanceState.getSerializable("timeframe");
	    }
	    else
	    {
	    	Bundle extras = getIntent().getExtras();
	    	
	    	if( extras != null )
	    		ret = extras.getString("timeframe");
	    	else
	    		ret = "weekdays";
	    }
		
		return ret;
	}
	
	/**
	 * Returns the Sting equivalent of the spinner position
	 * @param current spinner position
	 * @return String equivalent
	 */
	private String getPos(int current)
	{
		if(current == 0)
			return new String("weekdays");
		else if(current == 1)
			return new String("weekends");
		else
			return new String("reduced");
	}
	
	/**
	 * A "run array" is a string array of times when each
	 * stop is serviced.  Each run array id (references route3.xml)
	 * is added to the runs HashMap so that these array ids can 
	 * be referenced as strings in createGroupList() and 
	 * createChildList().
	 */
	private void addStringRuns()
	{
		// weekday stops
		runs.put( "r5stop1", R.array.r5stop1);
	    runs.put( "r5stop2", R.array.r5stop2);
	    runs.put( "r5stop3", R.array.r5stop3);
	    runs.put( "r5stop4", R.array.r5stop4);
	    runs.put( "r5stop5", R.array.r5stop5);
	    runs.put( "r5stop6", R.array.r5stop6);
	    runs.put( "r5stop7", R.array.r5stop7);
	    runs.put( "r5stop8", R.array.r5stop8);
	    runs.put( "r5stop9", R.array.r5stop9);
	    runs.put( "r5stop10", R.array.r5stop10);
	    runs.put( "r5stop11", R.array.r5stop11);
	    runs.put( "r5stop12", R.array.r5stop12);
	    runs.put( "r5stop13", R.array.r5stop13);
	    runs.put( "r5stop14", R.array.r5stop14);
	    runs.put( "r5stop15", R.array.r5stop15);
	    runs.put( "r5stop16", R.array.r5stop16);
	    runs.put( "r5stop17", R.array.r5stop17);
	    runs.put( "r5stop18", R.array.r5stop18);
	    runs.put( "r5stop19", R.array.r5stop19);
	    runs.put( "r5stop20", R.array.r5stop20);
	    runs.put( "r5stop21", R.array.r5stop21);
	    runs.put( "r5stop22", R.array.r5stop22);
	    runs.put( "r5stop23", R.array.r5stop23);
	    runs.put( "r5stop24", R.array.r5stop24);
	    runs.put( "r5stop25", R.array.r5stop25);
	    runs.put( "r5stop26", R.array.r5stop26);
	    
	    // weekend stops
	    runs.put( "r5wstop1", R.array.r5wstop1);
	    runs.put( "r5wstop2", R.array.r5wstop2);
	    runs.put( "r5wstop3", R.array.r5wstop3);
	    runs.put( "r5wstop4", R.array.r5wstop4);
	    runs.put( "r5wstop5", R.array.r5wstop5);
	    runs.put( "r5wstop6", R.array.r5wstop6);
	    runs.put( "r5wstop7", R.array.r5wstop7);
	    runs.put( "r5wstop8", R.array.r5wstop8);
	    runs.put( "r5wstop9", R.array.r5wstop9);
	    runs.put( "r5wstop10", R.array.r5wstop10);
	    runs.put( "r5wstop11", R.array.r5wstop11);
	    runs.put( "r5wstop12", R.array.r5wstop12);
	    runs.put( "r5wstop13", R.array.r5wstop13);
	    runs.put( "r5wstop14", R.array.r5wstop14);
	    runs.put( "r5wstop15", R.array.r5wstop15);
	    runs.put( "r5wstop16", R.array.r5wstop16);
	    runs.put( "r5wstop17", R.array.r5wstop17);
	    runs.put( "r5wstop18", R.array.r5wstop18);
	    runs.put( "r5wstop19", R.array.r5wstop19);
	    runs.put( "r5wstop20", R.array.r5wstop20);
	    runs.put( "r5wstop21", R.array.r5wstop21);
	    runs.put( "r5wstop22", R.array.r5wstop22);
	    runs.put( "r5wstop23", R.array.r5wstop23);
	    runs.put( "r5wstop24", R.array.r5wstop24);
	    runs.put( "r5wstop25", R.array.r5wstop25);
	    runs.put( "r5wstop26", R.array.r5wstop26);
	    
	    // reduced service stops
	    runs.put( "r5rstop1", R.array.r5rstop1);
	    runs.put( "r5rstop2", R.array.r5rstop2);
	    runs.put( "r5rstop3", R.array.r5rstop3);
	    runs.put( "r5rstop4", R.array.r5rstop4);
	    runs.put( "r5rstop5", R.array.r5rstop5);
	    runs.put( "r5rstop6", R.array.r5rstop6);
	    runs.put( "r5rstop7", R.array.r5rstop7);
	    runs.put( "r5rstop8", R.array.r5rstop8);
	    runs.put( "r5rstop9", R.array.r5rstop9);
	    runs.put( "r5rstop10", R.array.r5rstop10);
	    runs.put( "r5rstop11", R.array.r5rstop11);
	    runs.put( "r5rstop12", R.array.r5rstop12);
	    runs.put( "r5rstop13", R.array.r5rstop13);
	    runs.put( "r5rstop14", R.array.r5rstop14);
	    runs.put( "r5rstop15", R.array.r5rstop15);
	    runs.put( "r5rstop16", R.array.r5rstop16);
	    runs.put( "r5rstop17", R.array.r5rstop17);
	    runs.put( "r5rstop18", R.array.r5rstop18);
	    runs.put( "r5rstop19", R.array.r5rstop19);
	    runs.put( "r5rstop20", R.array.r5rstop20);
	    runs.put( "r5rstop21", R.array.r5rstop21);
	    runs.put( "r5rstop22", R.array.r5rstop22);
	    runs.put( "r5rstop23", R.array.r5rstop23);
	    runs.put( "r5rstop24", R.array.r5rstop24);
	    runs.put( "r5rstop25", R.array.r5rstop25);
	    runs.put( "r5rstop26", R.array.r5rstop26);
	}
	
	/**
	 * If the spinner item that was selected is different from the current
	 * spinner page, then it goes to the appropriate page.
	 *
	 */
	public class MyOnItemSelectedListener implements OnItemSelectedListener
	{		
	    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
	    	Intent i;
		    
	    	if( pos != spinnerState )
	    	{
	    		i = new Intent();
	    		i.setClass( ct, Route5Activity.class);
	    		i.putExtra("timeframe", getPos(pos));
	            startActivityForResult(i, 0);
	    	}
	    }

	    public void onNothingSelected(AdapterView<?> parent) {
	    	// Do nothing.
	    }
	}
	
	/**
	 * Saves the state of the screen.  This is called on orientation changes. 
	 */
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState)
	{
		  savedInstanceState.putString("timeframe", timeframe);
		  super.onSaveInstanceState(savedInstanceState);
	}
	
	/**
	 * Restore IU to original state.
	 */
	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState)
	{
		super.onRestoreInstanceState(savedInstanceState);
		//Restore UI state from the savedInstanceState.
		// This bundle has also been passed to onCreate.
		timeframe = savedInstanceState.getString("timeframe");
	}
}
